#include "debug.h"

#include "strings.h"
#include <stdarg.h>

#define _USE_INLINING

#ifdef WIN32
#include <windows.h>
#endif

eDebug::eDebug (void)
{
	/*
#ifdef WIN32
  DEV_NULL = &_iob [_IOB_ENTRIES - 1];
#else
  DEV_NULL = fopen ("/dev/null", "rbS");
#endif
  */

  last_error = EPSILON_NO_ERROR;
};

eDebug::~eDebug (void)
{
	/*
#ifndef WIN32
  fclose (DEV_NULL);
#endif
  */
};

EPSILON_API
bool
eCustomAssertFunction ( bool   expression,
			TCHAR* expression_str,
                        TCHAR* description,
                        int    lineNumber,
                        TCHAR* filename )
{
  if (! expression) {
    // TODO: use cstring for msg
    TCHAR msg [512];
    _sntprintf (msg, 512, _T ("%s\n\n")
    
                          _T (" Expression:\t%s\n")
                          _T (" Line:\t\t%d\n")
			                    _T (" File:\t\t%s\n\n")
			      
			                    _T ("  Continue?"),
			      description,
			      expression_str,
			      lineNumber,
			      filename);

    if (eMessageBoxEx (_T ("Assertion failed!"), msg, E_MB_YESNO | E_MB_ICONWARNING | E_MB_TASKMODAL) == E_IDYES)
      return false;

    return true;
  }

  return false;
}


EPSILON_API
void
eReportError (const int& iLine, const TCHAR* szFile, const TCHAR* szFormat, ...)
{
  TCHAR szDescription [2048];
  va_list ap;

  if (szFormat == NULL)
    return;

  va_start (ap, szFormat);
    _vsntprintf (szDescription, 2047, szFormat, ap);
  va_end (ap);

  TCHAR *pszFile = (TCHAR *)szFile;

  while (_tcsstr (pszFile, _T ("\\")))
    pszFile = (_tcsstr (pszFile, _T ("\\")) + 1);

  TCHAR szMessageBox [4096];
  _sntprintf ( szMessageBox,
               4095,         // No Buffer Overflows allowed! :)
              _T ("%s")      // Assume the error already has a linebreak!
              _T ("Source:\t[Line %d of %s]\n"),
//              _T ("NOTE:\tThe source line only indicates where the\n")
//              _T ("\terror was detected, not the actual cause"),
                 szDescription,
                 iLine, pszFile );

  eMessageBoxEx (_T ("Caught Unhandled Error"), szMessageBox, E_MB_OK);
}


EPSILON_API
int __cdecl
eMessageBeep (UINT uFlags)
{
#ifdef WIN32
  return MessageBeep (uFlags);
#else
  return 0; /// TODO: Replace with X11 equiv.
#endif
}


EPSILON_API
int __cdecl
eMessageBox (const TCHAR* szText)
{
  return eMessageBoxEx (_T ("Epsilon MessageBox"), szText, E_MB_OK);
}

EPSILON_API
int __cdecl
eMessageBoxEx (const TCHAR* szCaption, const TCHAR* szText, UINT uFlags)
{
#ifdef WIN32
  return MessageBox (NULL, szText, szCaption, uFlags);
#else
  TCHAR szFormattedMessage [1024];
  _sntprintf (szFormattedMessage, 1024, _T ("========================================"
                                            "========================================\n"
                                            "\t\t\t\t[%s]\n\n"
  
                                            "%s\n"),
					    szCaption,
					    szText);
  OutputDebugString (szFormattedMessage);

  _sntprintf (szFormattedMessage, 1024, _T ("\t\t\t\t  [(Y)es/(N)o]\n"
					    "========================================"
					    "========================================\n"));
  OutputDebugString (szFormattedMessage);

  
  return 0; /// TODO: Replace with X11 equiv.
#endif
}


EPSILON_API
int __cdecl
eMessageBoxF (const TCHAR* szFormat, ...)
{
  TCHAR szText [1024];

  va_list argv;

  // Don't try to format using a NULL format string!
  if (szFormat == NULL) {
    eSetLastError (EPSILON_ERROR_INVALID_DATA);
    return 0;
  }

  va_start (argv, szFormat);
    _vsntprintf (szText, 1023, szFormat, argv);
  va_end (argv);

  return eMessageBox (szText);
}

EPSILON_API
int __cdecl
eMessageBoxExF (const TCHAR* szCaption, UINT uFlags, const TCHAR* szFormat, ...)
{
  TCHAR szText [1024];

  va_list argv;

  // Don't try to format using a NULL format string!
  if (szFormat == NULL) {
    eSetLastError (EPSILON_ERROR_INVALID_DATA);
    return 0;
  }

  // Setup default flags if none are passed...
  if (! uFlags)
    uFlags = E_MB_OK;

  va_start (argv, szFormat);
    _vsntprintf (szText, 1023, szFormat, argv);
  va_end (argv);

  return eMessageBoxEx (szCaption, szText, uFlags);
}
